let X = 30,/* 格子数量 */
  Y = 30,
  gridH = 20 /* 格子高度 */,
  gridW = 20; /* 个自宽度 */
let game;
let number = 0,
  time = 220;
const score = document.querySelector('.score'); // 分数控制
const app = document.querySelector(".container") // 地图控制;
/* 创建方块dom */
class Grid {
  constructor(x, y, classname) {
    this.x = x * gridW; // gridW为每个格子的宽度(全局变量)，
    this.y = y * gridH;// gridH为每个格子的高度(全局变量)，
    this.classname = classname;
    this.viewContent = document.createElement("div");
    this.viewContent.className = this.classname;
    this.parent = document.querySelector(".snakewrap");
    this.create();
  }
  /* 创建 */
  create() {
    this.viewContent.style.left = this.x + "px";
    this.viewContent.style.top = this.y + "px";
    this.parent.appendChild(this.viewContent);
  }
  /* 删除 */
  remove() {
    this.parent.removeChild(this.viewContent);
  }
}
/* 蛇 */
class Snake {
  constructor() {
    this.status = false;
    this.head = null;
    this.tail = null;
    this.position = [];
    this.direction = {
      left: { x: -1, y: 0, rotate: 180 },
      right: { x: +1, y: 0, rotate: 0 },
      up: { x: 0, y: -1, rotate: -90},
      down: { x: 0,  y: +1 , rotate: 90},
  };
  }
  init() {
    /* 初始化一个蛇头 存储到位置arr */
    let snakehead = new Grid(2, 0, "snakehead");
    this.head = snakehead;
    this.position.push([2, 0]);
    let snakebody1 = new Grid(1, 0, "snakebody");
    this.position.push([1, 0]);
    let snakebody2 = new Grid(0, 0, "snakebody");
    this.position.push([0, 0]);
    this.tail = snakebody2;
    /* 蛇身之间的关系 start */
    snakehead.prevent = null;
    snakehead.next = snakebody1;
    snakebody1.prevent = snakehead;
    snakebody1.next = snakebody2
    snakebody2.prevent = snakebody1;
    snakebody2.next = null;
    /* 蛇身之间的关系 end */
    this.directionpos = this.direction.right; //默认向右走
  }
  /* 获取蛇的下一个位置的坐标 */
  getNextpos() {
    let isDie = false;
    let nextpos = [
      this.head.x / gridW + this.directionpos.x,
      this.head.y / gridH + this.directionpos.y,
    ];
    this.position.forEach((item) => {
      if (item[0] === nextpos[0] && item[1] === nextpos[1]) {
        isDie = true;
      }
    });
    /* 撞到自己了 */
    if (isDie) {
      console.log('撞到自己了');
      this.die();
      return true;
    }
    /* 撞墙了 */
    if (
      nextpos[1] < 0 ||
      nextpos[0] < 0 ||
      nextpos[0] > X - 1 ||
      nextpos[1] > Y - 1
    ) {
      this.die();
      return;
    }
    /* 碰到食物了 */
    if (nextpos[0] == this.foodpos[0] && nextpos[1] == this.foodpos[1]) {
      this.eat();
    } else {
      /* 下一步啥都没有 继续走*/
      this.move();
    }
  }
  move(isDelTail) {
    let newhead = new Grid(  // 创建新蛇头
      this.head.x / gridW + this.directionpos.x, 
      this.head.y / gridH + this.directionpos.y, "snakehead"
    );
    /* 将新的蛇头位置添加到数组中 */
    this.position.unshift([     
      this.head.x / gridW + this.directionpos.x,
      this.head.y / gridH + this.directionpos.y,
    ]);
    /* 更新链表关系 */
    this.head.prevent = newhead;
    newhead.prevent = null;
    newhead.next = this.head;
    this.head.viewContent.className = 'snakebody';
    this.head = newhead;
    /* 记录蛇头的方向 */
    newhead.viewContent.style.transform = `rotate(${this.directionpos.rotate}deg)`;
    if (!isDelTail) {
      this.tail.remove(this.tail);
      this.tail = this.tail.prevent; // 更新蛇尾
      this.position.pop();
    }
  }
  /* 速度控制 */
  speedController(speed) {
    clearInterval(game.timer);
      time = speed;
      game.start();
  }
  /* 吃食物 */
  eat() {
    number++; // 加分处理
    score.innerHTML = number; // 更新分数
    switch (number) { // 加速处理
      case 10:
        this.speedController(180); break;
      case 20:
        this.speedController(150); break;
      case 40:
        this.speedController(100); break;
      case 60:
        this.speedController(80); break;
      case 100:
        alter('恭喜你通关了！你真牛逼！');
        this.die(); 
        break;
    }
    this.move(true);
    /* 改变食物坐标 */
   this.createFood('food', false);
  }
  /* 死亡 */
  die() {
    clearInterval(game.timer);
    alert("您的得分：" + number);
    setTimeout(() => {
      document.querySelector(".snakewrap").innerText = "";
      snake = new Snake(); // 从新生成新的蛇
      game = new Game(); // 开启新的游戏
      number = 0;
      time = 220;
      score.innerHTML = number;
      startbtn = document.querySelector(".start");
      document.querySelector(".content").style.display = "block";
      startbtn.style.display = "block";
    }, 1000);
  }
  /* 判断食物是否长在蛇身上 */

  /* 创建食物 */
  createFood(classname, isFristGenerate) {
    this.food = isFristGenerate ? document.createElement("div") : document.querySelector(".food");
    this.parent = document.querySelector(".snakewrap");
    /* 食物不能长在蛇身上 */
    this.foodposx = parseInt(Math.round(Math.random() * (X - 1)));
    this.foodposy = parseInt(Math.round(Math.random() * (Y - 1)));
    this.foodpos = [this.foodposx,this.foodposy]; // 存储食物坐标
    this.status = false;
    this.position.forEach((item) => { // 判断是否生成的食物在蛇身上
      if (item[0] === this.foodpos[0] && item[1] === this.foodpos[1]) {
        this.status = true;
      }
    });
    if (this.status) {
      return this.createFood(classname, isFristGenerate);
    } else {
      this.food.style.left = this.foodposx * gridW + "px";
      this.food.style.top = this.foodposy * gridH + "px";
      isFristGenerate ? this.food.className = classname : '';
      isFristGenerate ? this.parent.appendChild(this.food) : '';
    }
  }
}

let snake = new Snake();

/* 游戏controller */
class Game {
  constructor() {
    this.timer = null;
    this.score = 0;
  }
  init() {
    snake.init();
    snake.createFood("food", true);
    document.addEventListener("keydown", (e) => {
      if (e.keyCode == 37 && snake.directionpos != snake.direction.right) {
        snake.directionpos = snake.direction.left;
      } else if (
        e.keyCode == 38 &&
        snake.directionpos != snake.direction.down
      ) {
        snake.directionpos = snake.direction.up;
      } else if (
        e.keyCode == 39 &&
        snake.directionpos != snake.direction.left
      ) {
        snake.directionpos = snake.direction.right;
      } else if (e.keyCode == 40 && snake.directionpos != snake.direction.up) {
        snake.directionpos = snake.direction.down;
      }
      snake.head.viewContent.style.transform = `rotate(${snake.directionpos.rotate}deg)`;
    });
    this.start();
  }
  start() {
    this.timer = setInterval(() => {
      snake.getNextpos();
    }, time);
  }
}
game = new Game();

/* 游戏逻辑处理部分 */
let startbtn = document.querySelector(".start");
startbtn.addEventListener(
  "click",
  () => {
    score.style.display = "block";
    startbtn.style.display = "none";
    document.querySelector(".content").style.display = "none";
    game.init();
  },
  false
);

document.querySelector(".container").addEventListener("mousedown", (e) => {
  if (e.target.className == "container") {
    clearInterval(game.timer);
    document.querySelector(".content").style.display = "block";
    document.querySelector(".keep").style.display = "block";
  }
});
document.querySelector(".keep").addEventListener(
  "click",
  () => {
    game.start();
    document.querySelector(".keep").style.display = "none";
    document.querySelector(".content").style.display = "none";
  },
  false
);

/* 得分处理 */
score.innerHTML = number;
